<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>面试官：你了解vue的diff算法吗？说说看 | vivace-itnerview</title>
    <meta name="description" content="interview docs">
    <link rel="stylesheet" href="/assets/style.f9ffe3f5.css">
    <link rel="modulepreload" href="/assets/chunks/VPAlgoliaSearchBox.ea0e7bf0.js">
    <link rel="modulepreload" href="/assets/app.1cdb2ec5.js">
    <link rel="modulepreload" href="/assets/vue_diff.md.37e2c3ee.lean.js">
    
    <link rel="icon" type="image/x-icon" href="/favicon.ico">
  <script id="check-dark-light">(()=>{const e=localStorage.getItem("vitepress-theme-appearance"),a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
  </head>
  <body>
    <div id="app"><div class="Layout" data-v-ca9ccb7e><!--[--><!--]--><!--[--><span tabindex="-1" data-v-151f2593></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-151f2593> Skip to content </a><!--]--><!----><header class="VPNav" data-v-ca9ccb7e data-v-a71a30f1><div class="VPNavBar has-sidebar" data-v-a71a30f1 data-v-a35e6f52><div class="container" data-v-a35e6f52><div class="VPNavBarTitle has-sidebar" data-v-a35e6f52 data-v-d5925166><a class="title" href="/" data-v-d5925166><!--[--><!--]--><!--[--><img class="VPImage logo" src="/logo.png" data-v-e13a1912><!--]--><!--[-->Web Interview<!--]--><!--[--><!--]--></a></div><div class="content" data-v-a35e6f52><!--[--><!--]--><div class="VPNavBarSearch search" data-v-a35e6f52 style="--38a1667b:&#39;Meta&#39;;"><div id="docsearch"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><svg class="DocSearch-Search-Icon" width="20" height="20" viewBox="0 0 20 20"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-a35e6f52 data-v-f83db6ba><span id="main-nav-aria-label" class="visually-hidden" data-v-f83db6ba>Main Navigation</span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/css/box.html" data-v-f83db6ba data-v-47a2263e data-v-3c355974><!--[-->CSS<!--]--><!----></a><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-f83db6ba data-v-6ffb57d3><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-6ffb57d3><span class="text" data-v-6ffb57d3><!----> JavaScript <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-6ffb57d3><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-6ffb57d3><div class="VPMenu" data-v-6ffb57d3 data-v-1c5d0cfc><div class="items" data-v-1c5d0cfc><!--[--><!--[--><div class="VPMenuLink" data-v-1c5d0cfc data-v-e8e0fb1d><a class="VPLink link" href="/JavaScript/data_type.html" data-v-e8e0fb1d data-v-3c355974><!--[-->JavaScript<!--]--><!----></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-1c5d0cfc data-v-e8e0fb1d><a class="VPLink link" href="/es6/var_let_const.html" data-v-e8e0fb1d data-v-3c355974><!--[-->es6<!--]--><!----></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-1c5d0cfc data-v-e8e0fb1d><a class="VPLink link" href="/typescript/typescript_javascript.html" data-v-e8e0fb1d data-v-3c355974><!--[-->Typescript<!--]--><!----></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-f83db6ba data-v-6ffb57d3><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-6ffb57d3><span class="text" data-v-6ffb57d3><!----> 框架 <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-6ffb57d3><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-6ffb57d3><div class="VPMenu" data-v-6ffb57d3 data-v-1c5d0cfc><div class="items" data-v-1c5d0cfc><!--[--><!--[--><div class="VPMenuLink" data-v-1c5d0cfc data-v-e8e0fb1d><a class="VPLink link" href="/vue/vue.html" data-v-e8e0fb1d data-v-3c355974><!--[-->Vue<!--]--><!----></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-1c5d0cfc data-v-e8e0fb1d><a class="VPLink link" href="/vue3/goal.html" data-v-e8e0fb1d data-v-3c355974><!--[-->Vue3<!--]--><!----></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-1c5d0cfc data-v-e8e0fb1d><a class="VPLink link" href="/React/React.html" data-v-e8e0fb1d data-v-3c355974><!--[-->React<!--]--><!----></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-1c5d0cfc data-v-e8e0fb1d><a class="VPLink link" href="/webpack/webpack.html" data-v-e8e0fb1d data-v-3c355974><!--[-->webpack<!--]--><!----></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/NodeJS/nodejs.html" data-v-f83db6ba data-v-47a2263e data-v-3c355974><!--[-->node<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/algorithm/Algorithm.html" data-v-f83db6ba data-v-47a2263e data-v-3c355974><!--[-->Algorithm<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/applet/applet.html" data-v-f83db6ba data-v-47a2263e data-v-3c355974><!--[-->小程序<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/http/HTTP_HTTPS.html" data-v-f83db6ba data-v-47a2263e data-v-3c355974><!--[-->http<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/git/version_control.html" data-v-f83db6ba data-v-47a2263e data-v-3c355974><!--[-->Git<!--]--><!----></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-a35e6f52 data-v-a3e7452b><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" aria-label="toggle dark mode" data-v-a3e7452b data-v-968780f1 data-v-086e8519><span class="check" data-v-086e8519><span class="icon" data-v-086e8519><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-968780f1><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-968780f1><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-a35e6f52 data-v-738bef5a data-v-f6988cfb><!--[--><a class="VPSocialLink" href="https://github.com/xiumubai" target="_blank" rel="noopener" data-v-f6988cfb data-v-e57698f6><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></a><!--]--></div><div class="VPFlyout VPNavBarExtra extra" data-v-a35e6f52 data-v-e89b88d7 data-v-6ffb57d3><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-6ffb57d3><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="icon" data-v-6ffb57d3><circle cx="12" cy="12" r="2"></circle><circle cx="19" cy="12" r="2"></circle><circle cx="5" cy="12" r="2"></circle></svg></button><div class="menu" data-v-6ffb57d3><div class="VPMenu" data-v-6ffb57d3 data-v-1c5d0cfc><!----><!--[--><!--[--><!----><div class="group" data-v-e89b88d7><div class="item appearance" data-v-e89b88d7><p class="label" data-v-e89b88d7>Appearance</p><div class="appearance-action" data-v-e89b88d7><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" aria-label="toggle dark mode" data-v-e89b88d7 data-v-968780f1 data-v-086e8519><span class="check" data-v-086e8519><span class="icon" data-v-086e8519><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-968780f1><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-968780f1><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div></div></div><div class="group" data-v-e89b88d7><div class="item social-links" data-v-e89b88d7><div class="VPSocialLinks social-links-list" data-v-e89b88d7 data-v-f6988cfb><!--[--><a class="VPSocialLink" href="https://github.com/xiumubai" target="_blank" rel="noopener" data-v-f6988cfb data-v-e57698f6><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></a><!--]--></div></div></div><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-a35e6f52 data-v-e5dd9c1c><span class="container" data-v-e5dd9c1c><span class="top" data-v-e5dd9c1c></span><span class="middle" data-v-e5dd9c1c></span><span class="bottom" data-v-e5dd9c1c></span></span></button></div></div></div><!----></header><div class="VPLocalNav" data-v-ca9ccb7e data-v-aac27d5e><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-aac27d5e><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="menu-icon" data-v-aac27d5e><path d="M17,11H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,11,17,11z"></path><path d="M21,7H3C2.4,7,2,6.6,2,6s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,7,21,7z"></path><path d="M21,15H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,15,21,15z"></path><path d="M17,19H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,19,17,19z"></path></svg><span class="menu-text" data-v-aac27d5e>Menu</span></button><a class="top-link" href="#" data-v-aac27d5e> Return to top </a></div><aside class="VPSidebar" data-v-ca9ccb7e data-v-f332cb62><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-f332cb62><span class="visually-hidden" id="sidebar-aria-label" data-v-f332cb62> Sidebar Navigation </span><!--[--><div class="group" data-v-f332cb62><section class="VPSidebarGroup collapsible" data-v-f332cb62 data-v-2976c796><div class="title" role="button" data-v-2976c796><h2 class="title-text" data-v-2976c796>Vue2 系列</h2><div class="action" data-v-2976c796><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 24 24" class="icon minus" data-v-2976c796><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2zM20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h8c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon plus" data-v-2976c796><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2z M20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11h-3V8c0-0.6-0.4-1-1-1s-1,0.4-1,1v3H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h3v3c0,0.6,0.4,1,1,1s1-0.4,1-1v-3h3c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg></div></div><div class="items" data-v-2976c796><!--[--><a class="VPLink link link" href="/vue/vue.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>1.说说你对vue的理解?</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/spa.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>2.说说你对SPA（单页应用）的理解?</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/show_if.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>3.Vue中的v-show和v-if怎么理解？</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/new_vue.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>4.Vue实例挂载的过程中发生了什么?</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/lifecycle.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>5.说说你对Vue生命周期的理解?</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/if_for.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>6.为什么Vue中的v-if和v-for不建议一起用?</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/first_page_time.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>7.SPA（单页应用）首屏加载速度慢怎么解决？</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/data.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>8.为什么data属性是一个函数而不是一个对象？</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/data_object_add_attrs.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>9.Vue中给对象添加新属性界面不刷新?</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/components_plugin.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>10.Vue中组件和插件有什么区别？</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/communication.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>11.Vue组件间通信方式都有哪些?</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/bind.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>12.说说你对双向绑定的理解?</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/nexttick.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>13.说说你对nexttick的理解?</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/mixin.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>14.说说你对vue的mixin的理解，有什么应用场景？</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/slot.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>15.说说你对slot的理解？slot使用场景有哪些？</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/observable.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>16.Vue.observable你有了解过吗？说说看</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/key.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>17.你知道vue中key的原理吗？说说你对它的理解？</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/keepalive.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>18.怎么缓存当前的组件？缓存后怎么更新？说说你对keep-alive的理解是什么？</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/modifier.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>19.Vue常用的修饰符有哪些？有什么应用场景？</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/directive.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>20.你有写过自定义指令吗？自定义指令的应用场景有哪些？</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/filter.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>21.Vue中的过滤器了解吗？过滤器的应用场景有哪些？</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/vnode.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>22.什么是虚拟DOM？如何实现一个虚拟DOM？说说你的思路</span><!----><!--]--><!----></a><a class="VPLink link link active" href="/vue/diff.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>23.你了解vue的diff算法吗？说说看</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/axios.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>24.Vue项目中有封装过axios吗？主要是封装哪方面的？</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/axiosCode.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>25.你了解axios的原理吗？有看过它的源码吗？</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/ssr.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>26.SSR解决了什么问题？有做过SSR吗？你是怎么做的？</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/structure.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>27.说下你的vue项目的目录结构，如果是大型项目你该怎么划分结构和划分组件呢？</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/permission.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>28.vue要做权限管理该怎么做？如果控制到按钮级别的权限怎么做？</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/cors.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>29.Vue项目中你是如何解决跨域的呢？</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/404.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>30.vue项目本地开发完成后部署到服务器后报404是什么原因呢？</span><!----><!--]--><!----></a><a class="VPLink link link" href="/vue/error.html" data-v-2976c796 data-v-f7e544fc data-v-3c355974><!--[--><span class="link-text" data-v-f7e544fc>31.你是怎么处理vue项目中的错误的？</span><!----><!--]--><!----></a><!--]--></div></section></div><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-ca9ccb7e data-v-c95df128><div class="VPDoc has-sidebar has-aside" data-v-c95df128 data-v-f0af2311><div class="container" data-v-f0af2311><div class="aside" data-v-f0af2311><div class="aside-curtain" data-v-f0af2311></div><div class="aside-container" data-v-f0af2311><div class="aside-content" data-v-f0af2311><div class="VPDocAside" data-v-f0af2311 data-v-aea49c31><!--[--><!--]--><!--[--><!--]--><div class="VPDocAsideOutline has-outline" data-v-aea49c31 data-v-a3de185c><div class="content" data-v-a3de185c><div class="outline-marker" data-v-a3de185c></div><div class="outline-title" data-v-a3de185c>On this page</div><nav aria-labelledby="doc-outline-aria-label" data-v-a3de185c><span class="visually-hidden" id="doc-outline-aria-label" data-v-a3de185c> Table of Contents for current page </span><ul class="root" data-v-a3de185c><!--[--><li data-v-a3de185c><a class="outline-link" href="#一、是什么" data-v-a3de185c>一、是什么</a><!----></li><li data-v-a3de185c><a class="outline-link" href="#二、比较方式" data-v-a3de185c>二、比较方式</a><!----></li><li data-v-a3de185c><a class="outline-link" href="#三、原理分析" data-v-a3de185c>三、原理分析</a><!----></li><li data-v-a3de185c><a class="outline-link" href="#参考文献" data-v-a3de185c>参考文献</a><!----></li><!--]--></ul></nav></div></div><!--[--><!--]--><div class="spacer" data-v-aea49c31></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-f0af2311><div class="content-container" data-v-f0af2311><!--[--><!--]--><main class="main" data-v-f0af2311><div style="position:relative;" class="vp-doc _vue_diff" data-v-f0af2311><div><h1 id="面试官：你了解vue的diff算法吗？说说看" tabindex="-1">面试官：你了解vue的diff算法吗？说说看 <a class="header-anchor" href="#面试官：你了解vue的diff算法吗？说说看" aria-hidden="true">#</a></h1><p><img src="https://static.vue-js.com/5e858e30-4585-11eb-85f6-6fac77c0c9b3.png" alt=""></p><h2 id="一、是什么" tabindex="-1">一、是什么 <a class="header-anchor" href="#一、是什么" aria-hidden="true">#</a></h2><p><code>diff</code> 算法是一种通过同层的树节点进行比较的高效算法</p><p>其有两个特点：</p><ul><li>比较只会在同层级进行, 不会跨层级比较</li><li>在diff比较的过程中，循环从两边向中间比较</li></ul><p><code>diff</code> 算法在很多场景下都有应用，在 <code>vue</code> 中，作用于虚拟 <code>dom</code> 渲染成真实 <code>dom</code> 的新旧 <code>VNode</code> 节点比较</p><h2 id="二、比较方式" tabindex="-1">二、比较方式 <a class="header-anchor" href="#二、比较方式" aria-hidden="true">#</a></h2><p><code>diff</code>整体策略为：深度优先，同层比较</p><ol><li>比较只会在同层级进行, 不会跨层级比较</li></ol><img src="https://static001.infoq.cn/resource/image/91/54/91e9c9519a11caa0c5bf70714383f054.png" alt="img" style="zoom:50%;"><ol start="2"><li>比较的过程中，循环从两边向中间收拢</li></ol><img src="https://static001.infoq.cn/resource/image/2d/ec/2dcd6ad5cf82c65b9cfc43a27ba1e4ec.png" alt="img" style="zoom:50%;"><p>下面举个<code>vue</code>通过<code>diff</code>算法更新的例子：</p><p>新旧<code>VNode</code>节点如下图所示：</p><p><img src="https://static001.infoq.cn/resource/image/80/6d/80dc339f73b186479e6d1fc18bfbf66d.png" alt=""></p><p>第一次循环后，发现旧节点D与新节点D相同，直接复用旧节点D作为<code>diff</code>后的第一个真实节点，同时旧节点<code>endIndex</code>移动到C，新节点的 <code>startIndex</code> 移动到了 C</p><p><img src="https://static001.infoq.cn/resource/image/76/54/76032c78c8ef74047efd42c070e48854.png" alt=""></p><p>第二次循环后，同样是旧节点的末尾和新节点的开头(都是 C)相同，同理，<code>diff</code> 后创建了 C 的真实节点插入到第一次创建的 D 节点后面。同时旧节点的 <code>endIndex</code> 移动到了 B，新节点的 <code>startIndex</code> 移动到了 E</p><p><img src="https://static001.infoq.cn/resource/image/1c/d7/1c76e7489660188d35f0a38ea8c8ecd7.png" alt=""></p><p>第三次循环中，发现E没有找到，这时候只能直接创建新的真实节点 E，插入到第二次创建的 C 节点之后。同时新节点的 <code>startIndex</code> 移动到了 A。旧节点的 <code>startIndex</code> 和 <code>endIndex</code> 都保持不动</p><p><img src="https://static001.infoq.cn/resource/image/4b/08/4b622c0d61673ec5474465d82305d308.png" alt=""></p><p>第四次循环中，发现了新旧节点的开头(都是 A)相同，于是 <code>diff</code> 后创建了 A 的真实节点，插入到前一次创建的 E 节点后面。同时旧节点的 <code>startIndex</code> 移动到了 B，新节点的<code> startIndex</code> 移动到了 B</p><p><img src="https://static001.infoq.cn/resource/image/59/b4/5982417c3e0b2fa9ae940354a0e67ab4.png" alt=""></p><p>第五次循环中，情形同第四次循环一样，因此 <code>diff</code> 后创建了 B 真实节点 插入到前一次创建的 A 节点后面。同时旧节点的 <code>startIndex </code>移动到了 C，新节点的 startIndex 移动到了 F</p><p><img src="https://static001.infoq.cn/resource/image/16/86/16cf0ef90f6e19d26c0ddffeca067e86.png" alt=""></p><p>新节点的 <code>startIndex</code> 已经大于 <code>endIndex</code> 了，需要创建 <code>newStartIdx</code> 和 <code>newEndIdx</code> 之间的所有节点，也就是节点F，直接创建 F 节点对应的真实节点放到 B 节点后面</p><p><img src="https://static001.infoq.cn/resource/image/dc/ad/dc215b45682cf6c9cc4700a5425673ad.png" alt=""></p><h2 id="三、原理分析" tabindex="-1">三、原理分析 <a class="header-anchor" href="#三、原理分析" aria-hidden="true">#</a></h2><p>当数据发生改变时，<code>set</code>方法会调用<code>Dep.notify</code>通知所有订阅者<code>Watcher</code>，订阅者就会调用<code>patch</code>给真实的<code>DOM</code>打补丁，更新相应的视图</p><p>源码位置：src/core/vdom/patch.js</p><div class="language-js"><button class="copy"></button><span class="lang">js</span><pre><code><span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">patch</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;">vnode</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;">hydrating</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;">removeOnly</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isUndef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">vnode</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#676E95;">// 没有新节点，直接执行destory钩子函数</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isDef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#F07178;">)) </span><span style="color:#82AAFF;">invokeDestroyHook</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">return</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">isInitialPatch</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#FF9CAC;">false</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">insertedVnodeQueue</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> []</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isUndef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">isInitialPatch</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#FF9CAC;">true</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#82AAFF;">createElm</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">vnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">insertedVnodeQueue</span><span style="color:#F07178;">) </span><span style="color:#676E95;">// 没有旧节点，直接用新节点生成dom元素</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">isRealElement</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">isDef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">nodeType</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#89DDFF;">!</span><span style="color:#A6ACCD;">isRealElement</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">sameVnode</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">vnode</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#676E95;">// 判断旧节点和新节点自身一样，一致执行patchVnode</span></span>
<span class="line"><span style="color:#F07178;">            </span><span style="color:#82AAFF;">patchVnode</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">vnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">insertedVnodeQueue</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">null,</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">null,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">removeOnly</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#676E95;">// 否则直接销毁及旧节点，根据新节点生成dom元素</span></span>
<span class="line"><span style="color:#F07178;">            </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">isRealElement</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;">                </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">nodeType</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">===</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">1</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">hasAttribute</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">SSR_ATTR</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">                    </span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">removeAttribute</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">SSR_ATTR</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">                    </span><span style="color:#A6ACCD;">hydrating</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#FF9CAC;">true</span></span>
<span class="line"><span style="color:#F07178;">                </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">                </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isTrue</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">hydrating</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">                    </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">hydrate</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">vnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">insertedVnodeQueue</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">                        </span><span style="color:#82AAFF;">invokeInsertHook</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">vnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">insertedVnodeQueue</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#FF9CAC;">true</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">                        </span><span style="color:#89DDFF;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldVnode</span></span>
<span class="line"><span style="color:#F07178;">                    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">                </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">                </span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">emptyNodeAt</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">            </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">            </span><span style="color:#89DDFF;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">vnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">elm</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">}</span></span>
<span class="line"></span></code></pre></div><p><code>patch</code>函数前两个参数位为<code>oldVnode</code> 和 <code>Vnode</code> ，分别代表新的节点和之前的旧节点，主要做了四个判断：</p><ul><li>没有新节点，直接触发旧节点的<code>destory</code>钩子</li><li>没有旧节点，说明是页面刚开始初始化的时候，此时，根本不需要比较了，直接全是新建，所以只调用 <code>createElm</code></li><li>旧节点和新节点自身一样，通过 <code>sameVnode</code> 判断节点是否一样，一样时，直接调用 <code>patchVnode </code>去处理这两个节点</li><li>旧节点和新节点自身不一样，当两个节点不一样的时候，直接创建新节点，删除旧节点</li></ul><p>下面主要讲的是<code>patchVnode</code>部分</p><div class="language-js"><button class="copy"></button><span class="lang">js</span><pre><code><span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">patchVnode</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;">vnode</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;">insertedVnodeQueue</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;">removeOnly</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;">// 如果新旧节点一致，什么都不做</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">===</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">vnode</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">return</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;">// 让vnode.el引用到现在的真实dom，当el修改时，vnode.el会同步变化</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">elm</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">vnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">elm</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">elm</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;">// 异步占位符</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isTrue</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">isAsyncPlaceholder</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isDef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">vnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">asyncFactory</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">resolved</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#82AAFF;">hydrate</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">elm</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">vnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">insertedVnodeQueue</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">vnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">isAsyncPlaceholder</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#FF9CAC;">true</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">return</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;">// 如果新旧都是静态节点，并且具有相同的key</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;">// 当vnode是克隆节点或是v-once指令控制的节点时，只需要把oldVnode.elm和oldVnode.child都复制到vnode上</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;">// 也不用再有其他操作</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isTrue</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">vnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">isStatic</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">&amp;&amp;</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#82AAFF;">isTrue</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">isStatic</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">&amp;&amp;</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#A6ACCD;">vnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">key</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">===</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">key</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span></span>
<span class="line"><span style="color:#F07178;">      (</span><span style="color:#82AAFF;">isTrue</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">vnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">isCloned</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">||</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">isTrue</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">vnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">isOnce</span><span style="color:#F07178;">))</span></span>
<span class="line"><span style="color:#F07178;">    ) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#A6ACCD;">vnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">componentInstance</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">componentInstance</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">return</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">i</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">data</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">vnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">data</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isDef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">data</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">isDef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">i</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">data</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hook</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">isDef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">i</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">i</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">prepatch</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#82AAFF;">i</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">vnode</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldCh</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">children</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">ch</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">vnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">children</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isDef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">data</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">isPatchable</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">vnode</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">for</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">i</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">;</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">i</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&lt;</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">cbs</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">update</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">length</span><span style="color:#89DDFF;">;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">++</span><span style="color:#A6ACCD;">i</span><span style="color:#F07178;">) </span><span style="color:#A6ACCD;">cbs</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">update</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">i</span><span style="color:#F07178;">](</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">vnode</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isDef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">i</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">data</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hook</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">isDef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">i</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">i</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">update</span><span style="color:#F07178;">)) </span><span style="color:#82AAFF;">i</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">vnode</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;">// 如果vnode不是文本节点或者注释节点</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isUndef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">vnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">text</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">      </span><span style="color:#676E95;">// 并且都有子节点</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isDef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldCh</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">isDef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">ch</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;">// 并且子节点不完全一致，则调用updateChildren</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">oldCh</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">!==</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">ch</span><span style="color:#F07178;">) </span><span style="color:#82AAFF;">updateChildren</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">elm</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldCh</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">ch</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">insertedVnodeQueue</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">removeOnly</span><span style="color:#F07178;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;">// 如果只有新的vnode有子节点</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isDef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">ch</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isDef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">text</span><span style="color:#F07178;">)) </span><span style="color:#A6ACCD;">nodeOps</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setTextContent</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">elm</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&#39;&#39;</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;">// elm已经引用了老的dom节点，在老的dom节点上添加子节点</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#82AAFF;">addVnodes</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">elm</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">null,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">ch</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">ch</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">length</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">-</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">insertedVnodeQueue</span><span style="color:#F07178;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;">// 如果新vnode没有子节点，而vnode有子节点，直接删除老的oldCh</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isDef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldCh</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#82AAFF;">removeVnodes</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">elm</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldCh</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">0</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldCh</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">length</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">-</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">1</span><span style="color:#F07178;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;">// 如果老节点是文本节点</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isDef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">text</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">nodeOps</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setTextContent</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">elm</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&#39;&#39;</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">      </span><span style="color:#676E95;">// 如果新vnode和老vnode是文本节点或注释节点</span></span>
<span class="line"><span style="color:#89DDFF;">      </span><span style="color:#676E95;">// 但是vnode.text != oldVnode.text时，只需要更新vnode.elm的文本内容就可以</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">text</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">!==</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">vnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">text</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#A6ACCD;">nodeOps</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setTextContent</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">elm</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">vnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">text</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isDef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">data</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isDef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">i</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">data</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">hook</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">isDef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">i</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">i</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">postpatch</span><span style="color:#F07178;">)) </span><span style="color:#82AAFF;">i</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">vnode</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span></code></pre></div><p><code>patchVnode</code>主要做了几个判断：</p><ul><li>新节点是否是文本节点，如果是，则直接更新<code>dom</code>的文本内容为新节点的文本内容</li><li>新节点和旧节点如果都有子节点，则处理比较更新子节点</li><li>只有新节点有子节点，旧节点没有，那么不用比较了，所有节点都是全新的，所以直接全部新建就好了，新建是指创建出所有新<code>DOM</code>，并且添加进父节点</li><li>只有旧节点有子节点而新节点没有，说明更新后的页面，旧节点全部都不见了，那么要做的，就是把所有的旧节点删除，也就是直接把<code>DOM</code> 删除</li></ul><p>子节点不完全一致，则调用<code>updateChildren</code></p><div class="language-js"><button class="copy"></button><span class="lang">js</span><pre><code><span class="line"><span style="color:#C792EA;">function</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">updateChildren</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;">parentElm</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;">oldCh</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;">newCh</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;">insertedVnodeQueue</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;">removeOnly</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldStartIdx</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">0</span><span style="color:#F07178;"> </span><span style="color:#676E95;">// 旧头索引</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newStartIdx</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">0</span><span style="color:#F07178;"> </span><span style="color:#676E95;">// 新头索引</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldEndIdx</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldCh</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">length</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">-</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">1</span><span style="color:#F07178;"> </span><span style="color:#676E95;">// 旧尾索引</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newEndIdx</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newCh</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">length</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">-</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">1</span><span style="color:#F07178;"> </span><span style="color:#676E95;">// 新尾索引</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldStartVnode</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldCh</span><span style="color:#F07178;">[</span><span style="color:#F78C6C;">0</span><span style="color:#F07178;">] </span><span style="color:#676E95;">// oldVnode的第一个child</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldEndVnode</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldCh</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">oldEndIdx</span><span style="color:#F07178;">] </span><span style="color:#676E95;">// oldVnode的最后一个child</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newStartVnode</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newCh</span><span style="color:#F07178;">[</span><span style="color:#F78C6C;">0</span><span style="color:#F07178;">] </span><span style="color:#676E95;">// newVnode的第一个child</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newEndVnode</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newCh</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">newEndIdx</span><span style="color:#F07178;">] </span><span style="color:#676E95;">// newVnode的最后一个child</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">let</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldKeyToIdx</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">idxInOld</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">vnodeToMove</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">refElm</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;">// removeOnly is a special flag used only by &lt;transition-group&gt;</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;">// to ensure removed elements stay in correct relative positions</span></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;">// during leaving transitions</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">canMove</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">!</span><span style="color:#A6ACCD;">removeOnly</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">    </span><span style="color:#676E95;">// 如果oldStartVnode和oldEndVnode重合，并且新的也都重合了，证明diff完了，循环结束</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">while</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">oldStartIdx</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&lt;=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldEndIdx</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newStartIdx</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&lt;=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newEndIdx</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">      </span><span style="color:#676E95;">// 如果oldVnode的第一个child不存在</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isUndef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldStartVnode</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;">// oldStart索引右移</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">oldStartVnode</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldCh</span><span style="color:#F07178;">[</span><span style="color:#89DDFF;">++</span><span style="color:#A6ACCD;">oldStartIdx</span><span style="color:#F07178;">] </span><span style="color:#676E95;">// Vnode has been moved left</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">      </span><span style="color:#676E95;">// 如果oldVnode的最后一个child不存在</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isUndef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldEndVnode</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;">// oldEnd索引左移</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">oldEndVnode</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldCh</span><span style="color:#F07178;">[</span><span style="color:#89DDFF;">--</span><span style="color:#A6ACCD;">oldEndIdx</span><span style="color:#F07178;">]</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">      </span><span style="color:#676E95;">// oldStartVnode和newStartVnode是同一个节点</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">sameVnode</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldStartVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newStartVnode</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;">// patch oldStartVnode和newStartVnode， 索引左移，继续循环</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#82AAFF;">patchVnode</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldStartVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newStartVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">insertedVnodeQueue</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">oldStartVnode</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldCh</span><span style="color:#F07178;">[</span><span style="color:#89DDFF;">++</span><span style="color:#A6ACCD;">oldStartIdx</span><span style="color:#F07178;">]</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">newStartVnode</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newCh</span><span style="color:#F07178;">[</span><span style="color:#89DDFF;">++</span><span style="color:#A6ACCD;">newStartIdx</span><span style="color:#F07178;">]</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">      </span><span style="color:#676E95;">// oldEndVnode和newEndVnode是同一个节点</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">sameVnode</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldEndVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newEndVnode</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;">// patch oldEndVnode和newEndVnode，索引右移，继续循环</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#82AAFF;">patchVnode</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldEndVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newEndVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">insertedVnodeQueue</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">oldEndVnode</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldCh</span><span style="color:#F07178;">[</span><span style="color:#89DDFF;">--</span><span style="color:#A6ACCD;">oldEndIdx</span><span style="color:#F07178;">]</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">newEndVnode</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newCh</span><span style="color:#F07178;">[</span><span style="color:#89DDFF;">--</span><span style="color:#A6ACCD;">newEndIdx</span><span style="color:#F07178;">]</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">      </span><span style="color:#676E95;">// oldStartVnode和newEndVnode是同一个节点</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">sameVnode</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldStartVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newEndVnode</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#676E95;">// Vnode moved right</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;">// patch oldStartVnode和newEndVnode</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#82AAFF;">patchVnode</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldStartVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newEndVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">insertedVnodeQueue</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;">// 如果removeOnly是false，则将oldStartVnode.eml移动到oldEndVnode.elm之后</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">canMove</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">nodeOps</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">insertBefore</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">parentElm</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldStartVnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">elm</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">nodeOps</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">nextSibling</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldEndVnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">elm</span><span style="color:#F07178;">))</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;">// oldStart索引右移，newEnd索引左移</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">oldStartVnode</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldCh</span><span style="color:#F07178;">[</span><span style="color:#89DDFF;">++</span><span style="color:#A6ACCD;">oldStartIdx</span><span style="color:#F07178;">]</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">newEndVnode</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newCh</span><span style="color:#F07178;">[</span><span style="color:#89DDFF;">--</span><span style="color:#A6ACCD;">newEndIdx</span><span style="color:#F07178;">]</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">      </span><span style="color:#676E95;">// 如果oldEndVnode和newStartVnode是同一个节点</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">sameVnode</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldEndVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newStartVnode</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#676E95;">// Vnode moved left</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;">// patch oldEndVnode和newStartVnode</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#82AAFF;">patchVnode</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldEndVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newStartVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">insertedVnodeQueue</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;">// 如果removeOnly是false，则将oldEndVnode.elm移动到oldStartVnode.elm之前</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">canMove</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">nodeOps</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">insertBefore</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">parentElm</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldEndVnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">elm</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldStartVnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">elm</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;">// oldEnd索引左移，newStart索引右移</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">oldEndVnode</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldCh</span><span style="color:#F07178;">[</span><span style="color:#89DDFF;">--</span><span style="color:#A6ACCD;">oldEndIdx</span><span style="color:#F07178;">]</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">newStartVnode</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newCh</span><span style="color:#F07178;">[</span><span style="color:#89DDFF;">++</span><span style="color:#A6ACCD;">newStartIdx</span><span style="color:#F07178;">]</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">      </span><span style="color:#676E95;">// 如果都不匹配</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isUndef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldKeyToIdx</span><span style="color:#F07178;">)) </span><span style="color:#A6ACCD;">oldKeyToIdx</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">createKeyToOldIdx</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">oldCh</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldStartIdx</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldEndIdx</span><span style="color:#F07178;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;">// 尝试在oldChildren中寻找和newStartVnode的具有相同的key的Vnode</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">idxInOld</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">isDef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">newStartVnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">key</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">          </span><span style="color:#89DDFF;">?</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldKeyToIdx</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">newStartVnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">key</span><span style="color:#F07178;">]</span></span>
<span class="line"><span style="color:#F07178;">          </span><span style="color:#89DDFF;">:</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">findIdxInOld</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">newStartVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldCh</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldStartIdx</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldEndIdx</span><span style="color:#F07178;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;">// 如果未找到，说明newStartVnode是一个新的节点</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">isUndef</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">idxInOld</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span><span style="color:#F07178;"> </span><span style="color:#676E95;">// New element</span></span>
<span class="line"><span style="color:#89DDFF;">          </span><span style="color:#676E95;">// 创建一个新Vnode</span></span>
<span class="line"><span style="color:#F07178;">          </span><span style="color:#82AAFF;">createElm</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">newStartVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">insertedVnodeQueue</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">parentElm</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldStartVnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">elm</span><span style="color:#F07178;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;">// 如果找到了和newStartVnodej具有相同的key的Vnode，叫vnodeToMove</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">          </span><span style="color:#A6ACCD;">vnodeToMove</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldCh</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">idxInOld</span><span style="color:#F07178;">]</span></span>
<span class="line"><span style="color:#F07178;">          </span><span style="color:#676E95;">/* istanbul ignore if */</span></span>
<span class="line"><span style="color:#F07178;">          </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#A6ACCD;">process</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">env</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">NODE_ENV</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">!==</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">production</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">!</span><span style="color:#A6ACCD;">vnodeToMove</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">            </span><span style="color:#82AAFF;">warn</span><span style="color:#F07178;">(</span></span>
<span class="line"><span style="color:#F07178;">              </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">It seems there are duplicate keys that is causing an update error. </span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">+</span></span>
<span class="line"><span style="color:#F07178;">              </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">Make sure each v-for item has a unique key.</span><span style="color:#89DDFF;">&#39;</span></span>
<span class="line"><span style="color:#F07178;">            )</span></span>
<span class="line"><span style="color:#F07178;">          </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">          </span><span style="color:#676E95;">// 比较两个具有相同的key的新节点是否是同一个节点</span></span>
<span class="line"><span style="color:#89DDFF;">          </span><span style="color:#676E95;">//不设key，newCh和oldCh只会进行头尾两端的相互比较，设key后，除了头尾两端的比较外，还会从用key生成的对象oldKeyToIdx中查找匹配的节点，所以为节点设置key可以更高效的利用dom。</span></span>
<span class="line"><span style="color:#F07178;">          </span><span style="color:#89DDFF;">if</span><span style="color:#F07178;"> (</span><span style="color:#82AAFF;">sameVnode</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">vnodeToMove</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newStartVnode</span><span style="color:#F07178;">)) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#676E95;">// patch vnodeToMove和newStartVnode</span></span>
<span class="line"><span style="color:#F07178;">            </span><span style="color:#82AAFF;">patchVnode</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">vnodeToMove</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newStartVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">insertedVnodeQueue</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#676E95;">// 清除</span></span>
<span class="line"><span style="color:#F07178;">            </span><span style="color:#A6ACCD;">oldCh</span><span style="color:#F07178;">[</span><span style="color:#A6ACCD;">idxInOld</span><span style="color:#F07178;">] </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">undefined</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#676E95;">// 如果removeOnly是false，则将找到的和newStartVnodej具有相同的key的Vnode，叫vnodeToMove.elm</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#676E95;">// 移动到oldStartVnode.elm之前</span></span>
<span class="line"><span style="color:#F07178;">            </span><span style="color:#A6ACCD;">canMove</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">nodeOps</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">insertBefore</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">parentElm</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">vnodeToMove</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">elm</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldStartVnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">elm</span><span style="color:#F07178;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">          </span><span style="color:#676E95;">// 如果key相同，但是节点不相同，则创建一个新的节点</span></span>
<span class="line"><span style="color:#F07178;">          </span><span style="color:#89DDFF;">}</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">else</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">            </span><span style="color:#676E95;">// same key but different element. treat as new element</span></span>
<span class="line"><span style="color:#F07178;">            </span><span style="color:#82AAFF;">createElm</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">newStartVnode</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">insertedVnodeQueue</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">parentElm</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">oldStartVnode</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">elm</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">          </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#89DDFF;">        </span><span style="color:#676E95;">// 右移</span></span>
<span class="line"><span style="color:#F07178;">        </span><span style="color:#A6ACCD;">newStartVnode</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">newCh</span><span style="color:#F07178;">[</span><span style="color:#89DDFF;">++</span><span style="color:#A6ACCD;">newStartIdx</span><span style="color:#F07178;">]</span></span>
<span class="line"><span style="color:#F07178;">      </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;">}</span></span>
<span class="line"></span></code></pre></div><p><code>while</code>循环主要处理了以下五种情景：</p><ul><li>当新老 <code>VNode</code> 节点的 <code>start</code> 相同时，直接 <code>patchVnode</code> ，同时新老 <code>VNode</code> 节点的开始索引都加 1</li><li>当新老 <code>VNode</code> 节点的 <code>end</code>相同时，同样直接 <code>patchVnode</code> ，同时新老 <code>VNode</code> 节点的结束索引都减 1</li><li>当老 <code>VNode</code> 节点的 <code>start</code> 和新 <code>VNode</code> 节点的 <code>end</code> 相同时，这时候在 <code>patchVnode</code> 后，还需要将当前真实 <code>dom</code> 节点移动到 <code>oldEndVnode</code> 的后面，同时老 <code>VNode</code> 节点开始索引加 1，新 <code>VNode</code> 节点的结束索引减 1</li><li>当老 <code>VNode</code> 节点的 <code>end</code> 和新 <code>VNode</code> 节点的 <code>start</code> 相同时，这时候在 <code>patchVnode</code> 后，还需要将当前真实 <code>dom</code> 节点移动到 <code>oldStartVnode</code> 的前面，同时老 <code>VNode</code> 节点结束索引减 1，新 <code>VNode</code> 节点的开始索引加 1</li><li>如果都不满足以上四种情形，那说明没有相同的节点可以复用，则会分为以下两种情况： <ul><li>从旧的 <code>VNode</code> 为 <code>key</code> 值，对应 <code>index</code> 序列为 <code>value</code> 值的哈希表中找到与 <code>newStartVnode</code> 一致 <code>key</code> 的旧的 <code>VNode</code> 节点，再进行<code>patchVnode </code>，同时将这个真实 <code>dom </code>移动到 <code>oldStartVnode</code> 对应的真实 <code>dom</code> 的前面</li><li>调用 <code>createElm</code> 创建一个新的 <code>dom</code> 节点放到当前 <code>newStartIdx</code> 的位置</li></ul></li></ul><h3 id="小结" tabindex="-1">小结 <a class="header-anchor" href="#小结" aria-hidden="true">#</a></h3><ul><li>当数据发生改变时，订阅者<code>watcher</code>就会调用<code>patch</code>给真实的<code>DOM</code>打补丁</li><li>通过<code>isSameVnode</code>进行判断，相同则调用<code>patchVnode</code>方法</li><li><code>patchVnode</code>做了以下操作： <ul><li>找到对应的真实<code>dom</code>，称为<code>el</code></li><li>如果都有都有文本节点且不相等，将<code>el</code>文本节点设置为<code>Vnode</code>的文本节点</li><li>如果<code>oldVnode</code>有子节点而<code>VNode</code>没有，则删除<code>el</code>子节点</li><li>如果<code>oldVnode</code>没有子节点而<code>VNode</code>有，则将<code>VNode</code>的子节点真实化后添加到<code>el</code></li><li>如果两者都有子节点，则执行<code>updateChildren</code>函数比较子节点</li></ul></li><li><code>updateChildren</code>主要做了以下操作： <ul><li>设置新旧<code>VNode</code>的头尾指针</li><li>新旧头尾指针进行比较，循环向中间靠拢，根据情况调用<code>patchVnode</code>进行<code>patch</code>重复流程、调用<code>createElem</code>创建一个新节点，从哈希表寻找 <code>key</code>一致的<code>VNode</code> 节点再分情况操作</li></ul></li></ul><h2 id="参考文献" tabindex="-1">参考文献 <a class="header-anchor" href="#参考文献" aria-hidden="true">#</a></h2><ul><li><a href="https://juejin.cn/post/6881907432541552648#heading-1" target="_blank" rel="noreferrer">https://juejin.cn/post/6881907432541552648#heading-1</a></li><li><a href="https://www.infoq.cn/article/udlcpkh4iqb0cr5wgy7f" target="_blank" rel="noreferrer">https://www.infoq.cn/article/udlcpkh4iqb0cr5wgy7f</a></li></ul></div></div></main><!--[--><!--]--><footer class="VPDocFooter" data-v-f0af2311 data-v-a54a85bd><div class="edit-info" data-v-a54a85bd><!----><div class="last-updated" data-v-a54a85bd><p class="VPLastUpdated" data-v-a54a85bd data-v-f7d51a9c>Last updated: <time datatime="2022-09-22T09:50:29.000Z" data-v-f7d51a9c></time></p></div></div><div class="prev-next" data-v-a54a85bd><div class="pager" data-v-a54a85bd><a class="pager-link prev" href="/vue/vnode.html" data-v-a54a85bd><span class="desc" data-v-a54a85bd>Previous page</span><span class="title" data-v-a54a85bd>22.什么是虚拟DOM？如何实现一个虚拟DOM？说说你的思路</span></a></div><div class="has-prev pager" data-v-a54a85bd><a class="pager-link next" href="/vue/axios.html" data-v-a54a85bd><span class="desc" data-v-a54a85bd>Next page</span><span class="title" data-v-a54a85bd>24.Vue项目中有封装过axios吗？主要是封装哪方面的？</span></a></div></div></footer><!--[--><!--]--></div></div></div></div></div><footer class="VPFooter has-sidebar" data-v-ca9ccb7e data-v-9f24cc86><div class="container" data-v-9f24cc86><p class="message" data-v-9f24cc86>Released under the MIT License.</p><p class="copyright" data-v-9f24cc86>Copyright © 2022-present xiumubai</p></div></footer><!--[--><!--]--></div></div>
    <script>__VP_HASH_MAP__ = JSON.parse("{\"javascript_bom.md\":\"b4feb213\",\"javascript_dom.md\":\"115217f2\",\"javascript_ajax.md\":\"4cd66d00\",\"javascript_array_api.md\":\"fc7e9f5e\",\"javascript_bind_call_apply.md\":\"5037ea1f\",\"javascript_cache.md\":\"3cab1e33\",\"javascript_closure.md\":\"a011a286\",\"javascript_compare.md\":\"8bd00b66\",\"javascript_context_stack.md\":\"eff24dfd\",\"javascript_continue_to_upload.md\":\"8b9f775e\",\"javascript_copy.md\":\"9e6f3d4e\",\"javascript_data_type.md\":\"6773ee7f\",\"javascript_debounce_throttle.md\":\"37f66fe3\",\"javascript_event_model.md\":\"df25b298\",\"javascript_event_agent.md\":\"de86b13f\",\"javascript_event_loop.md\":\"ec105c46\",\"javascript_function_cache.md\":\"722b5929\",\"javascript_functional_programming.md\":\"74c57d2b\",\"javascript_inherit.md\":\"bfe04b52\",\"javascript_js_data_structure.md\":\"3d5793d5\",\"javascript_loss_accuracy.md\":\"4a5e1e83\",\"javascript_memory_leak.md\":\"7f468176\",\"javascript_new.md\":\"a7c10c2f\",\"javascript_prototype.md\":\"ba4aad9c\",\"javascript_pull_up_loading_pull_down_refresh.md\":\"bcd55b26\",\"javascript_regexp.md\":\"5cdd425f\",\"javascript_scope.md\":\"19d93e6d\",\"javascript_security.md\":\"5bc240c7\",\"javascript_single_sign.md\":\"22b66bf9\",\"javascript_string_api.md\":\"4431266e\",\"javascript_tail_recursion.md\":\"d10c1177\",\"javascript_this.md\":\"67dd8f3a\",\"javascript_type_conversion.md\":\"089b68ca\",\"javascript_typeof_instanceof.md\":\"a0ea8297\",\"javascript_visible.md\":\"1b8c1427\",\"nodejs_buffer.md\":\"86b6fada\",\"nodejs_eventemitter.md\":\"4424fd2c\",\"nodejs_stream.md\":\"b2fa0025\",\"nodejs_event_loop.md\":\"03c1b709\",\"nodejs_file_upload.md\":\"37ab2103\",\"nodejs_fs.md\":\"9221e437\",\"nodejs_global.md\":\"a1b3fd28\",\"nodejs_jwt.md\":\"d986798b\",\"nodejs_middleware.md\":\"c2c968c4\",\"nodejs_nodejs.md\":\"6ba067a4\",\"nodejs_paging.md\":\"8b76e487\",\"nodejs_performance.md\":\"fa9c1623\",\"nodejs_process.md\":\"3d717454\",\"nodejs_require_order.md\":\"6e9b880f\",\"react_binding events.md\":\"606997b9\",\"react_building components.md\":\"2460627f\",\"react_fiber.md\":\"e3a3ac5c\",\"react_high order components.md\":\"804cdc8c\",\"react_improve performance.md\":\"2b4cd579\",\"react_jsx to dom.md\":\"7da96f4e\",\"react_react hooks.md\":\"ac1889e4\",\"react_react router model.md\":\"d7e60a7d\",\"react_react router.md\":\"58e50995\",\"react_react refs.md\":\"a90f5a94\",\"react_react.md\":\"6c1f12f1\",\"react_real dom_virtual dom.md\":\"78c68534\",\"react_redux middleware.md\":\"f9c0c1a5\",\"react_syntheticevent.md\":\"937038a1\",\"react_animation.md\":\"51b808f8\",\"react_capture error.md\":\"ab82c7b3\",\"react_class_function component.md\":\"dec93b8e\",\"react_communication.md\":\"63ecc8dd\",\"react_controlled_uncontrolled.md\":\"929967ab\",\"react_diff.md\":\"6758822a\",\"react_how to use redux.md\":\"87b15e2e\",\"react_immutable.md\":\"32f831f3\",\"react_import css.md\":\"6b24701d\",\"react_improve_render.md\":\"0080c4c8\",\"react_key.md\":\"8b76383f\",\"react_life cycle.md\":\"ffcbc76b\",\"react_redux.md\":\"e2fcb8f3\",\"react_render.md\":\"a9b9a91f\",\"react_server side rendering.md\":\"1cbca1f2\",\"react_setstate.md\":\"03ba5fb6\",\"react_state_props.md\":\"b80f455f\",\"react_summary.md\":\"47a9aa61\",\"react_super()_super(props).md\":\"e5fd40c9\",\"algorithm_algorithm.md\":\"6f482d8b\",\"algorithm_binarysearch.md\":\"3a4c14f4\",\"algorithm_heap.md\":\"fe5839ed\",\"algorithm_linked list.md\":\"ec192250\",\"algorithm_bubblesort.md\":\"cf87b40d\",\"algorithm_design1.md\":\"bd491cfe\",\"algorithm_design2.md\":\"941bf6ba\",\"algorithm_graph.md\":\"ddab9801\",\"algorithm_insertionsort.md\":\"7ad6d0c6\",\"algorithm_mergesort.md\":\"d704839d\",\"algorithm_quicksort.md\":\"04e65ce9\",\"algorithm_selectionsort.md\":\"c751f8ed\",\"algorithm_set.md\":\"aa1a236e\",\"algorithm_sort.md\":\"69fbb06f\",\"algorithm_stack_queue.md\":\"09cb42c4\",\"algorithm_structure.md\":\"8ceb1498\",\"algorithm_time_space.md\":\"20afcad9\",\"algorithm_tree.md\":\"8880d846\",\"applet_webview_jscore.md\":\"b5d697c3\",\"applet_applet.md\":\"fd446e94\",\"applet_lifecycle.md\":\"fdf96326\",\"applet_login.md\":\"000d8413\",\"applet_navigate.md\":\"661447e1\",\"applet_optimization.md\":\"4483173a\",\"applet_publish.md\":\"75f5f978\",\"applet_requestpayment.md\":\"96dce311\",\"css_bfc.md\":\"be6458b1\",\"css_animation.md\":\"c69b6036\",\"css_box.md\":\"134dc0e2\",\"css_center.md\":\"671d90b4\",\"css_column_layout.md\":\"17662907\",\"css_css3_features.md\":\"07c233e8\",\"css_css_performance.md\":\"1e723fed\",\"css_dp_px_dpr_ppi.md\":\"baf193db\",\"css_em_px_rem_vh_vw.md\":\"d8841819\",\"css_flexbox.md\":\"60b4d3a2\",\"css_grid.md\":\"fe9da145\",\"css_hide_attributes.md\":\"294742dd\",\"css_layout_painting.md\":\"0b4c79e9\",\"css_less_12px.md\":\"0b872326\",\"css_responsive_layout.md\":\"a92ea8dd\",\"css_sass_less_stylus.md\":\"35f379b9\",\"css_selector.md\":\"17b6992a\",\"css_single_multi_line.md\":\"139fb49a\",\"css_triangle.md\":\"445f3e5e\",\"css_visual_scrolling.md\":\"b22bdee4\",\"demo_index.md\":\"90a5f28c\",\"es6_array.md\":\"b2d9c780\",\"es6_decorator.md\":\"0155aa71\",\"es6_function.md\":\"b2a54be3\",\"es6_generator.md\":\"ab397709\",\"es6_module.md\":\"8074618d\",\"es6_object.md\":\"02960089\",\"es6_promise.md\":\"ba7c72e0\",\"es6_proxy.md\":\"5d343ca0\",\"es6_set_map.md\":\"16366c0a\",\"es6_var_let_const.md\":\"94c5a2e5\",\"git_git.md\":\"81cfa072\",\"git_head_tree_index.md\":\"8da2b48e\",\"git_command.md\":\"d398f681\",\"git_conflict.md\":\"6ace32b7\",\"git_fork_clone_branch.md\":\"60d8b215\",\"git_git_pull_git_fetch.md\":\"7ba61a26\",\"git_git_rebase_git_merge.md\":\"24044b46\",\"git_git_reset_git_revert.md\":\"0573874e\",\"git_git_stash.md\":\"b2108bb4\",\"git_version_control.md\":\"5315b3a1\",\"http_1.0_1.1_2.0.md\":\"f4855f53\",\"http_cdn.md\":\"8db3cb9d\",\"http_dns.md\":\"5bb40fe6\",\"http_get_post.md\":\"54952aa8\",\"http_https.md\":\"42a442c8\",\"http_http_https.md\":\"584d2870\",\"http_osi.md\":\"feab35f0\",\"http_tcp_ip.md\":\"9a3280d8\",\"http_udp_tcp.md\":\"8d5731e8\",\"http_websocket.md\":\"b78e9a8f\",\"http_after_url.md\":\"ed13fb23\",\"http_handshakes_waves.md\":\"7f21a38c\",\"http_headers.md\":\"77af020f\",\"http_status.md\":\"731daad7\",\"index.md\":\"b249642b\",\"typescript_class.md\":\"3bc756f0\",\"typescript_data_type.md\":\"8b852fca\",\"typescript_decorator.md\":\"09934301\",\"typescript_enum.md\":\"f05a48e4\",\"typescript_function.md\":\"aa1f6c95\",\"typescript_generic.md\":\"066edb51\",\"typescript_high type.md\":\"bdf59b40\",\"typescript_interface.md\":\"3ebee750\",\"typescript_namespace_module.md\":\"2af77e9c\",\"typescript_react.md\":\"6ca91139\",\"typescript_typescript_javascript.md\":\"e89507d8\",\"typescript_vue.md\":\"a39dd1b5\",\"vue_404.md\":\"1b714ff3\",\"vue_axios.md\":\"a1e96e5f\",\"vue_axioscode.md\":\"fccd1ad0\",\"vue_bind.md\":\"4c20085d\",\"vue_communication.md\":\"3f059e41\",\"vue_components_plugin.md\":\"2b4f21b2\",\"vue_cors.md\":\"6aede5b3\",\"vue_data.md\":\"18d617df\",\"vue_data_object_add_attrs.md\":\"94cf2218\",\"vue_diff.md\":\"37e2c3ee\",\"vue_directive.md\":\"9b5aed0e\",\"vue_error.md\":\"347dc9f7\",\"vue_filter.md\":\"ff72d81c\",\"vue_first_page_time.md\":\"1cf8d795\",\"vue_if_for.md\":\"28139518\",\"vue_keepalive.md\":\"b8401dc5\",\"vue_key.md\":\"05160f3e\",\"vue_lifecycle.md\":\"21135238\",\"vue_mixin.md\":\"ed53004e\",\"vue_modifier.md\":\"f82a3264\",\"vue_new_vue.md\":\"0244ca48\",\"vue_nexttick.md\":\"dd0380b1\",\"vue_observable.md\":\"edc5c364\",\"vue_permission.md\":\"90cc7a15\",\"vue_show_if.md\":\"706a56de\",\"vue_slot.md\":\"820aa4ac\",\"vue_spa.md\":\"75e55e32\",\"vue_ssr.md\":\"3f6ba2de\",\"vue_structure.md\":\"170a36be\",\"vue_vnode.md\":\"a1edc5ce\",\"vue_vue.md\":\"07289420\",\"vue3_composition.md\":\"4ca97a72\",\"vue3_goal.md\":\"7224e393\",\"vue3_modal_component.md\":\"7245015a\",\"vue3_performance.md\":\"535b5faa\",\"vue3_proxy.md\":\"17acfa40\",\"vue3_treeshaking.md\":\"8732cc75\",\"webpack_hmr.md\":\"2bf5fb55\",\"webpack_loader.md\":\"5a6680be\",\"webpack_loader_plugin.md\":\"01307ebe\",\"webpack_plugin.md\":\"fb205e68\",\"webpack_rollup_parcel_snowpack_vite.md\":\"2ce2d9e1\",\"webpack_build_process.md\":\"fbd4e2e7\",\"webpack_improve_build.md\":\"496f4f12\",\"webpack_performance.md\":\"ebeffcd8\",\"webpack_proxy.md\":\"3619d807\",\"webpack_webpack.md\":\"0fddbfa8\"}")</script>
    <script type="module" async src="/assets/app.1cdb2ec5.js"></script>
    
  </body>
</html>